home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume7 / des < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  25.8 KB

  1. Subject:  v07i027:  Purported DES program in C
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: cca!caip!lll-crg!hoptoad!gnu (John Gilmore)
  6. Mod.sources: Volume 7, Issue 27
  7. Archive-name: des
  8.  
  9. [  I wrote the Makefile and manpage.  Before compiling this program, you
  10.    will want to take a look at the non-standard fopen calls.  I believe
  11.    the "rb" and "wb" parameters are instructions to open the file in
  12.    'binary' (8bit, no newline mapping) mode for some MS-DOS compilers.
  13.    --r$  ]
  14.  
  15. #!/bin/sh
  16. # This is a shell archive.  Remove anything before this line,
  17. # then unpack it by saving it in a file and typing "sh file".
  18. # If all goes well, you will see the message "No problems found."
  19. # Wrapped by mirror!rs on Mon Sep 15 00:14:18 EDT 1986
  20.  
  21. # Exit status; set to 1 on "wc" errors or if would overwrite.
  22. STATUS=0
  23. # Contents:  README Makefile des.1 des.c
  24.  
  25. echo x - README
  26. if test -f README ; then
  27.     echo README exists, putting output in $$README
  28.     OUT=$$README
  29.     STATUS=1
  30. else
  31.     OUT=README
  32. fi
  33. sed 's/^X//' > $OUT <<'@//E*O*F README//'
  34. XThis program came from a cryptography related BBS near Washington, DC.
  35. XI have been unable to verify whether it works.  It does compile and run
  36. Xon 4.2BSD (Sun Unix).  However, the other DES implementation I have
  37. Xavailable (Sun's) uses a different format for keys.  I wish both would
  38. Xallow you to type the 56-bit key as 14 digits of hex -- but neither one
  39. Xdoes, they do different transformations of 8 bytes of ASCII.
  40.  
  41. XIf anyone has the DES validation samples [from the standard or its 
  42. Xaccompanying publications], please post them.
  43.  
  44. XNote that I do not recommend the use of DES if you want to keep your
  45. Xdata secure.  All that can be said for it is that fewer people know
  46. Xhow to break it than crypt(1).
  47. @//E*O*F README//
  48. chmod u=rw,g=rw,o=rw $OUT
  49.  
  50. echo x - Makefile
  51. if test -f Makefile ; then
  52.     echo Makefile exists, putting output in $$Makefile
  53.     OUT=$$Makefile
  54.     STATUS=1
  55. else
  56.     OUT=Makefile
  57. fi
  58. sed 's/^X//' > $OUT <<'@//E*O*F Makefile//'
  59. Xdes:    des.c
  60. X    cc -O -o des des.c
  61.  
  62. X# these targets are for my BSD system; your mileage will vary.
  63. Xinstall:    des
  64. X    cp des /usr/bin/des
  65. X    cp des.1 /usr/man/man1/des.1
  66. @//E*O*F Makefile//
  67. chmod u=rw,g=rw,o=rw $OUT
  68.  
  69. echo x - des.1
  70. if test -f des.1 ; then
  71.     echo des.1 exists, putting output in $$des.1
  72.     OUT=$$des.1
  73.     STATUS=1
  74. else
  75.     OUT=des.1
  76. fi
  77. sed 's/^X//' > $OUT <<'@//E*O*F des.1//'
  78. X.TH DES 1  LOCAL
  79. X.SH NAME
  80. Xdes \- perform DES encryption on a file
  81. X.SH SYNOPSIS
  82. X.B des
  83. Xfilename
  84. X.SH DESCRIPTION
  85. XThis program takes a single argument, a file to encrypt or decrypt.
  86. XWhen started, it asks for a password.
  87. XIf the file is named like ``foo.n'' the file is decrypted with the given key,
  88. Xand output is put into the file ``foo.''
  89. XOtherwise, if the file is named like ``foo,'' the file is encrypted and
  90. Xthe output is put into ``foo.n''.
  91. XIn both cases, the original input file is removed.
  92. X.SH "SEE ALSO"
  93. Xcrypt(1)
  94. X.SH BUGS
  95. XMay not be true DES.
  96. @//E*O*F des.1//
  97. chmod u=rw,g=rw,o=rw $OUT
  98.  
  99. echo x - des.c
  100. if test -f des.c ; then
  101.     echo des.c exists, putting output in $$des.c
  102.     OUT=$$des.c
  103.     STATUS=1
  104. else
  105.     OUT=des.c
  106. fi
  107. sed 's/^X//' > $OUT <<'@//E*O*F des.c//'
  108. X/* des: duplicate the NBS Data Encryption Standard in software.
  109. X * usage: des <file>
  110. X * prompts for the password
  111. X * If the filename ends in ".n" it will be decrypted with the key;
  112. X * otherwise it will be encrypted.
  113. X *
  114. X * Permutation algorithm:
  115. X *    The permutation is defined by its effect on each of the 16 nibbles
  116. X *    of the 64-bit input.  For each nibble we give an 8-byte bit array
  117. X *    that has the bits in the input nibble distributed correctly.  The
  118. X *    complete permutation involves ORing the 16 sets of 8 bytes designated
  119. X *    by the 16 input nibbles.  Uses 16*16*8 = 2K bytes of storage for
  120. X *    each 64-bit permutation.  32-bit permutations (P) and expansion (E)
  121. X *    are done similarly, but using bytes instead of nibbles.
  122. X *    Should be able to use long ints, adding the masks, at a
  123. X *    later pass.  Tradeoff: can speed 64-bit perms up at cost of slowing 
  124. X *    down expansion or contraction operations by using 8K tables here and
  125. X *    decreasing the size of the other tables.
  126. X * The compressions are pre-computed in 12-bit chunks, combining 2 of the
  127. X *    6->4 bit compressions.
  128. X * The key schedule is also precomputed.
  129. X * Compile with VALIDATE defined to run the NBS validation suite.
  130. X *
  131. X * Jim Gillogly, May 1977
  132. X * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  133. X *   post-1977 C compilers and systems
  134. X *
  135. X * This program is now officially in the public domain, and is available for
  136. X * any non-profit use as long as the authorship line is retained.
  137. X */
  138.  
  139. X/*#define VALIDATE    */    /* define to check the NBS validation suite */
  140. X/*#define DEBUG     */
  141. X/*#define LATTICE    */    /* define for Lattice C on IBM PC */
  142.  
  143. X#include <stdio.h>
  144.  
  145. X#ifndef LATTICE
  146. X#include <sgtty.h>
  147. X#include <signal.h>
  148. X#include <sys/types.h>  /* for local timer */
  149. X#include <sys/timeb.h>  /* ditto */
  150.  
  151. Xstruct sgttyb ttybuf;            /* for gtty/stty         */
  152. Xint bye();                /* for caught interrupts     */
  153.  
  154. X#endif
  155.  
  156. Xchar iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
  157. Xchar s[4][4096];            /* S1 thru S8 precomputed    */
  158. Xchar p32[4][256][4];            /* for permuting 32-bit f output*/
  159. Xchar kn[16][6];                /* key selections        */
  160.  
  161. Xendes(inblock,outblock)            /* encrypt 64-bit inblock    */
  162. Xchar *inblock, *outblock;
  163. X{    char iters[17][8];        /* workspace for each iteration */
  164. X    char swap[8];            /* place to interchange L and R */
  165. X    register int i;
  166. X    register char *s, *t;
  167.  
  168. X    permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  169. X    for (i=0; i<16; i++)        /* 16 churning operations    */
  170. X        iter(i,iters[i],iters[i+1]);
  171. X                    /* don't re-copy to save space  */
  172. X    s = swap; t = &iters[16][4];    /* interchange left        */
  173. X    *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  174. X    t = &iters[16][0];        /* and right            */
  175. X    *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  176. X    permute(swap,fperm,outblock);   /* apply final permutation    */
  177. X}
  178.  
  179. Xdedes(inblock,outblock)            /* decrypt 64-bit inblock    */
  180. Xchar *inblock,*outblock;
  181. X{    char iters[17][8];        /* workspace for each iteration */
  182. X    char swap[8];            /* place to interchange L and R */
  183. X    register int i;
  184. X    register char *s, *t;
  185.  
  186. X    permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  187. X    for (i=0; i<16; i++)        /* 16 churning operations    */
  188. X        iter(15-i,iters[i],iters[i+1]);
  189. X                    /* reverse order from encrypting*/
  190. X    s = swap; t = &iters[16][4];    /* interchange left        */
  191. X    *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  192. X    t = &iters[16][0];        /* and right            */
  193. X    *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  194. X    permute(swap,fperm,outblock);   /* apply final permutation    */
  195. X}
  196.  
  197. Xpermute(inblock,perm,outblock)        /* permute inblock with perm    */
  198. Xchar *inblock, *outblock;        /* result into outblock,64 bits */
  199. Xchar perm[16][16][8];            /* 2K bytes defining perm.    */
  200. X{    register int i,j;
  201. X    register char *ib, *ob;        /* ptr to input or output block */
  202. X    register char *p, *q;
  203.  
  204. X    for (i=0, ob = outblock; i<8; i++)
  205. X        *ob++ = 0;        /* clear output block        */
  206. X    ib = inblock;
  207. X    for (j = 0; j < 16; j += 2, ib++) /* for each input nibble    */
  208. X    {    ob = outblock;
  209. X        p = perm[j][(*ib >> 4) & 017];
  210. X        q = perm[j + 1][*ib & 017];
  211. X        for (i = 0; i < 8; i++)   /* and each output byte    */
  212. X            *ob++ |= *p++ | *q++;   /* OR the masks together*/
  213. X    }
  214. X}
  215.  
  216. Xchar ip[]                /* initial permutation P    */
  217. X= {    58, 50, 42, 34, 26, 18, 10,  2,
  218. X    60, 52, 44, 36, 28, 20, 12,  4,
  219. X    62, 54, 46, 38, 30, 22, 14,  6,
  220. X    64, 56, 48, 40, 32, 24, 16,  8,
  221. X    57, 49, 41, 33, 25, 17,  9,  1,
  222. X    59, 51, 43, 35, 27, 19, 11,  3,
  223. X    61, 53, 45, 37, 29, 21, 13,  5,
  224. X    63, 55, 47, 39, 31, 23, 15,  7    };
  225.  
  226. Xchar fp[]                /* final permutation F      */
  227. X= {    40,  8, 48, 16, 56, 24, 64, 32,
  228. X    39,  7, 47, 15, 55, 23, 63, 31,
  229. X    38,  6, 46, 14, 54, 22, 62, 30,
  230. X    37,  5, 45, 13, 53, 21, 61, 29,
  231. X    36,  4, 44, 12, 52, 20, 60, 28,
  232. X    35,  3, 43, 11, 51, 19, 59, 27,
  233. X    34,  2, 42, 10, 50, 18, 58, 26,
  234. X    33,  1, 41,  9, 49, 17, 57, 25    };
  235.  
  236. X/* expansion operation matrix   */    /* rwo: unused    */
  237. X/* char ei[] = {    32,  1,  2,  3,  4,  5,
  238. X     4,  5,  6,  7,  8,  9,
  239. X     8,  9, 10, 11, 12, 13,
  240. X    12, 13, 14, 15, 16, 17,
  241. X    16, 17, 18, 19, 20, 21,
  242. X    20, 21, 22, 23, 24, 25,
  243. X    24, 25, 26, 27, 28, 29,
  244. X    28, 29, 30, 31, 32,  1  };    */
  245.  
  246. Xchar pc1[]                /* permuted choice table (key)  */
  247. X= {    57, 49, 41, 33, 25, 17,  9,
  248. X     1, 58, 50, 42, 34, 26, 18,
  249. X    10,  2, 59, 51, 43, 35, 27,
  250. X    19, 11,  3, 60, 52, 44, 36,
  251.  
  252. X    63, 55, 47, 39, 31, 23, 15,
  253. X     7, 62, 54, 46, 38, 30, 22,
  254. X    14,  6, 61, 53, 45, 37, 29,
  255. X    21, 13,  5, 28, 20, 12,  4    };
  256.  
  257. Xchar totrot[]               /* number left rotations of pc1 */
  258. X= {    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28    };
  259.  
  260. Xchar pc1m[56];              /* place to modify pc1 into    */
  261. Xchar pcr[56];               /* place to rotate pc1 into    */
  262.  
  263. Xchar pc2[]                /* permuted choice key (table)  */
  264. X= {    14, 17, 11, 24,  1,  5,
  265. X     3, 28, 15,  6, 21, 10,
  266. X    23, 19, 12,  4, 26,  8,
  267. X    16,  7, 27, 20, 13,  2,
  268. X    41, 52, 31, 37, 47, 55,
  269. X    30, 40, 51, 45, 33, 48,
  270. X    44, 49, 39, 56, 34, 53,
  271. X    46, 42, 50, 36, 29, 32    };
  272.  
  273. Xchar si[8][64]              /* 48->32 bit compression tables*/
  274. X= {                    /* S[1]             */
  275. X    14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  276. X     0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  277. X     4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  278. X    15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  279. X                    /* S[2]             */
  280. X    15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  281. X     3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  282. X     0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  283. X    13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  284. X                    /* S[3]             */
  285. X    10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  286. X    13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  287. X    13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  288. X     1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  289. X                    /* S[4]             */
  290. X     7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  291. X    13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  292. X    10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  293. X     3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  294. X                    /* S[5]             */
  295. X     2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  296. X    14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  297. X     4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  298. X    11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  299. X                    /* S[6]             */
  300. X    12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  301. X    10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  302. X     9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  303. X     4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  304. X                    /* S[7]             */
  305. X     4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  306. X    13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  307. X     1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  308. X     6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  309. X                    /* S[8]             */
  310. X    13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  311. X     1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  312. X     7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  313. X     2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    };
  314.  
  315. Xchar p32i[]                /* 32-bit permutation function  */
  316. X= {    16,  7, 20, 21,
  317. X    29, 12, 28, 17,
  318. X     1, 15, 23, 26,
  319. X     5, 18, 31, 10,
  320. X     2,  8, 24, 14,
  321. X    32, 27,  3,  9,
  322. X    19, 13, 30,  6,
  323. X    22, 11,  4, 25    };
  324.  
  325. Xdesinit(key)                /* initialize all des arrays    */
  326. Xchar *key;
  327. X{
  328. X#ifdef DEBUG
  329. X/*deb*/ printf("Initial perm init.\n");
  330. X#endif
  331. X    perminit(iperm,ip);        /* initial permutation        */
  332. X#ifdef DEBUG
  333. X/*deb*/ printf("Final perm init.\n");
  334. X#endif
  335. X    perminit(fperm,fp);        /* final permutation        */
  336. X#ifdef DEBUG
  337. X/*deb*/ printf("Key sched init.\n");
  338. X#endif
  339. X    kinit(key);            /* key schedule            */
  340. X#ifdef DEBUG
  341. X/*deb*/ printf("Compression init.\n");
  342. X#endif
  343. X    sinit();            /* compression functions    */
  344.  
  345. X#ifdef DEBUG
  346. X/*deb*/ printf("32-bit perm init.\n");
  347. X#endif
  348. X    p32init();            /* 32-bit permutation in f    */
  349. X#ifdef DEBUG
  350. X/*deb*/ printf("End init.\n");
  351. X#endif
  352. X}
  353.  
  354. Xint bytebit[]               /* bit 0 is left-most in byte    */
  355. X    = {    0200,0100,040,020,010,04,02,01 };
  356.  
  357. Xint nibblebit[] = { 010,04,02,01 };
  358.  
  359. Xsinit()                 /* initialize s1-s8 arrays        */
  360. X{    register int i,j;
  361.  
  362. X    for (i=0; i<4; i++)        /* each 12-bit position        */
  363. X        for (j=0; j<4096; j++)  /* each possible 12-bit value   */
  364. X            s[i][j]=(getcomp(i*2,j>>6)<<4) |
  365. X                (017&getcomp(i*2+1,j&077));
  366. X                    /* store 2 compressions per char*/
  367. X}
  368.  
  369. Xgetcomp(k,v)                /* 1 compression value for sinit*/
  370. Xint k,v;
  371. X{    register int i,j;        /* correspond to i and j in FIPS*/
  372.  
  373. X    i=((v&040)>>4)|(v&1);        /* first and last bits make row */
  374. X    j=(v&037)>>1;            /* middle 4 bits are column    */
  375. X    return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
  376. X}
  377.  
  378. Xkinit(key)                /* initialize key schedule array*/
  379. Xchar *key;                /* 64 bits (will use only 56)   */
  380. X{    register int i,j,l;
  381. X    int m;
  382.  
  383. X    for (j=0; j<56; j++)        /* convert pc1 to bits of key   */
  384. X    {    l=pc1[j]-1;        /* integer bit location        */
  385. X        m = l & 07;        /* find bit            */
  386. X        pc1m[j]=(key[l>>3] &    /* find which key byte l is in  */
  387. X            bytebit[m])    /* and which bit of that byte   */
  388. X            ? 1 : 0;    /* and store 1-bit result    */
  389. X    }
  390. X    for (i=0; i<16; i++)        /* for each key sched section   */
  391. X        for (j=0; j<6; j++)    /* and each byte of the kn    */
  392. X            kn[i][j]=0;    /* clear it for accumulation    */
  393. X    for (i=0; i<16; i++)        /* key chunk for each iteration */
  394. X    {    for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  395. X        pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  396. X            /* rotate left and right halves independently   */
  397. X        for (j=0; j<48; j++)    /* select bits individually    */
  398. X        if (pcr[pc2[j]-1])    /* check bit that goes to kn[j] */
  399. X            {    l= j & 07;
  400. X                kn[i][j>>3] |= bytebit[l];
  401. X            }        /* mask it in if it's there    */
  402. X    }
  403. X}
  404.  
  405. Xp32init()                /* initialize 32-bit permutation*/
  406. X{    register int l, j, k;
  407. X    int i,m;
  408.  
  409. X    for (i=0; i<4; i++)        /* each input byte position    */
  410. X        for (j=0; j<256; j++)    /* all possible input bytes    */
  411. X        for (k=0; k<4; k++)    /* each byte of the mask    */
  412. X            p32[i][j][k]=0;    /* clear permutation array    */
  413. X    for (i=0; i<4; i++)        /* each input byte position    */
  414. X        for (j=0; j<256; j++)    /* each possible input byte    */
  415. X        for (k=0; k<32; k++)    /* each output bit position    */
  416. X        {   l=p32i[k]-1;    /* invert this bit (0-31)    */
  417. X            if ((l>>3)!=i)    /* does it come from input posn?*/
  418. X            continue;    /* if not, bit k is 0        */
  419. X            if (!(j&bytebit[l&07]))
  420. X            continue;    /* any such bit in input?    */
  421. X            m = k & 07;     /* which bit is it?        */
  422. X            p32[i][j][k>>3] |= bytebit[m];
  423. X        }
  424. X}
  425.  
  426. Xperminit(perm,p)            /* initialize a perm array    */
  427. Xchar perm[16][16][8];            /* 64-bit, either init or final */
  428. Xchar p[64];
  429. X{    register int l, j, k;
  430. X    int i,m;
  431.  
  432. X    for (i=0; i<16; i++)        /* each input nibble position   */
  433. X        for (j=0; j<16; j++)    /* all possible input nibbles   */
  434. X        for (k=0; k<8; k++)    /* each byte of the mask    */
  435. X            perm[i][j][k]=0;/* clear permutation array    */
  436. X    for (i=0; i<16; i++)        /* each input nibble position   */
  437. X        for (j = 0; j < 16; j++)/* each possible input nibble   */
  438. X        for (k = 0; k < 64; k++)/* each output bit position    */
  439. X        {   l = p[k] - 1;    /* where does this bit come from*/
  440. X            if ((l >> 2) != i)  /* does it come from input posn?*/
  441. X            continue;    /* if not, bit k is 0        */
  442. X            if (!(j & nibblebit[l & 3]))
  443. X            continue;    /* any such bit in input?    */
  444. X            m = k & 07;    /* which bit is this in the byte*/
  445. X            perm[i][j][k>>3] |= bytebit[m];
  446. X        }
  447. X}
  448.  
  449. Xiter(num,inblock,outblock)        /* 1 churning operation        */
  450. Xint num;                /* i.e. the num-th one        */
  451. Xchar *inblock, *outblock;        /* 64 bits each            */
  452. X{    char fret[4];            /* return from f(R[i-1],key)    */
  453. X    register char *ib, *ob, *fb;
  454. X/*    register int i;    */    /* rwo: unused    */
  455.  
  456. X    ob = outblock; ib = &inblock[4];
  457. X    f(ib, num, fret);        /* the primary transformation   */
  458. X    *ob++ = *ib++;            /* L[i] = R[i-1]        */
  459. X    *ob++ = *ib++;
  460. X    *ob++ = *ib++;
  461. X    *ob++ = *ib++;
  462. X    ib = inblock; fb = fret;    /* R[i]=L[i] XOR f(R[i-1],key)  */
  463. X    *ob++ = *ib++ ^ *fb++;
  464. X    *ob++ = *ib++ ^ *fb++;
  465. X    *ob++ = *ib++ ^ *fb++;
  466. X    *ob++ = *ib++ ^ *fb++;
  467. X}
  468.  
  469. Xf(right,num,fret)            /* critical cryptographic trans */
  470. Xchar *right, *fret;            /* 32 bits each            */
  471. Xint num;                /* index number of this iter    */
  472. X{    register char *kb, *rb, *bb;    /* ptr to key selection &c    */
  473. X    char bigright[6];        /* right expanded to 48 bits    */
  474. X    char result[6];            /* expand(R) XOR keyselect[num] */
  475. X    char preout[4];            /* result of 32-bit permutation */
  476.  
  477. X    kb = kn[num];            /* fast version of iteration    */
  478. X    bb = bigright;
  479. X    rb = result;
  480. X    expand(right,bb);        /* expand to 48 bits        */
  481. X    *rb++ = *bb++ ^ *kb++;        /* expanded R XOR chunk of key  */
  482. X    *rb++ = *bb++ ^ *kb++;
  483. X    *rb++ = *bb++ ^ *kb++;
  484. X    *rb++ = *bb++ ^ *kb++;
  485. X    *rb++ = *bb++ ^ *kb++;
  486. X    *rb++ = *bb++ ^ *kb++;
  487. X    contract(result,preout);    /* use S fns to get 32 bits    */
  488. X    perm32(preout,fret);        /* and do final 32-bit perm    */
  489. X}
  490.  
  491. Xperm32(inblock,outblock)        /* 32-bit permutation at end    */
  492. Xchar *inblock,*outblock;        /* of the f crypto function    */
  493. X{    register int j;
  494. X/*    register int i;    */    /* rwo: unused    */
  495. X    register char *ib, *ob;
  496. X    register char *q;
  497.  
  498. X    ob = outblock;            /* clear output block        */
  499. X    *ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
  500. X    ib=inblock;            /* ptr to 1st byte of input    */
  501. X    for (j=0; j<4; j++, ib++)    /* for each input byte        */
  502. X    {    q = p32[j][*ib & 0377];
  503. X        ob = outblock;        /* and each output byte        */
  504. X        *ob++ |= *q++;        /* OR the 16 masks together    */
  505. X        *ob++ |= *q++;
  506. X        *ob++ |= *q++;
  507. X        *ob++ |= *q++;
  508. X    }
  509. X}
  510.  
  511. Xexpand(right,bigright)            /* 32 to 48 bits with E oper    */
  512. Xchar *right,*bigright;            /* right is 32, bigright 48    */
  513. X{
  514. X    register char *bb, *r, r0, r1, r2, r3;
  515.  
  516. X    bb = bigright;
  517. X    r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
  518. X    *bb++ = ((r3 & 0001) << 7) |    /* 32                */
  519. X        ((r0 & 0370) >> 1) |    /* 1 2 3 4 5            */
  520. X        ((r0 & 0030) >> 3);    /* 4 5                */
  521. X    *bb++ = ((r0 & 0007) << 5) |    /* 6 7 8            */
  522. X        ((r1 & 0200) >> 3) |    /* 9                */
  523. X        ((r0 & 0001) << 3) |    /* 8                */
  524. X        ((r1 & 0340) >> 5);    /* 9 10 11            */
  525. X    *bb++ = ((r1 & 0030) << 3) |    /* 12 13            */
  526. X        ((r1 & 0037) << 1) |    /* 12 13 14 15 16        */
  527. X        ((r2 & 0200) >> 7);    /* 17                */
  528. X    *bb++ = ((r1 & 0001) << 7) |    /* 16                */
  529. X        ((r2 & 0370) >> 1) |    /* 17 18 19 20 21        */
  530. X        ((r2 & 0030) >> 3);    /* 20 21            */
  531. X    *bb++ = ((r2 & 0007) << 5) |    /* 22 23 24            */
  532. X        ((r3 & 0200) >> 3) |    /* 25                */
  533. X        ((r2 & 0001) << 3) |    /* 24                */
  534. X        ((r3 & 0340) >> 5);    /* 25 26 27            */
  535. X    *bb++ = ((r3 & 0030) << 3) |    /* 28 29            */
  536. X        ((r3 & 0037) << 1) |    /* 28 29 30 31 32        */
  537. X        ((r0 & 0200) >> 7);    /* 1                */
  538. X}
  539.  
  540. Xcontract(in48,out32)            /* contract f from 48 to 32 bits*/
  541. Xchar *in48,*out32;            /* using 12-bit pieces into bytes */
  542. X{    register char *c;
  543. X    register char *i;
  544. X    register int i0, i1, i2, i3, i4, i5;
  545.  
  546. X    i = in48;
  547. X    i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
  548. X    c = out32;            /* do output a byte at a time   */
  549. X    *c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
  550. X    *c++ = s[1][07777 & ((i1 << 8) | ( i2    & 0377 ))];
  551. X    *c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
  552. X    *c++ = s[3][07777 & ((i4 << 8) | ( i5    & 0377 ))];
  553. X}
  554.  
  555. X/* End of DES algorithm (except for calling desinit below)    */
  556.  
  557. X#ifndef VALIDATE
  558. Xchar *inname, *outname;
  559. XFILE *infile, *outfile;
  560.  
  561. Xint encrypting;
  562. Xchar buf[512];
  563. Xchar keyx[9], keyy[9];
  564.  
  565. Xchar *malloc(), *strcpy(), *strcat();
  566.  
  567. Xmain(argc, argv)
  568. Xint argc; char *argv[];
  569. X{    register char *u;
  570. X    char *filename;
  571.  
  572. X    if (argc < 2)            /* filenames given? */
  573. X    {  fprintf(stderr, "Usage: des file ...\n");
  574. X       exit(1);     
  575. X    }
  576.  
  577. X    for (++argv; --argc; ++argv)
  578. X    {    inname = *argv;
  579. X        outname = filename = malloc((unsigned) strlen(inname) + 3);
  580. X        strcpy(filename, inname);
  581. X        u = &filename[strlen(filename) - 2]; /* check last 2 chars */
  582.  
  583. X        encrypting = (strcmp(".n", u) != 0);
  584. X        if (!encrypting) *u = 0; /* strip .n from output filename */
  585. X        else strcat(filename, ".n");  /* or add .n to output file */
  586.  
  587. X        if ((infile = fopen(inname, "rb")) == NULL)
  588. X        {    fprintf(stderr,"Can't read %s.\n", inname);
  589. X            exit(1);
  590. X        }
  591. X        if ((outfile = fopen(outname, "rb")) != NULL)
  592. X        {    fprintf(stderr, "%s would be overwritten.\n",outname);
  593. X            exit(1);
  594. X        }
  595. X        if ((outfile = fopen(outname, "wb")) == NULL)
  596. X        {    fprintf(stderr,"Can't write %s.\n", outname);
  597. X            exit(1);
  598. X        }
  599.  
  600. X        key_get("Type password for ");
  601. X        for (;;)
  602. X        {    strcpy(keyx, keyy);
  603. X            key_get("Verify password for ");
  604. X            if (strcmp(keyx, keyy) == 0) break;
  605. X        }
  606. X        desinit(keyx);      /* set up tables for DES    */
  607.  
  608. X        if (pfile() == 0) unlink(inname);
  609. X        else    fprintf(stderr,
  610. X               "%s: I/O Error -- File unchanged\n", inname);
  611.  
  612. X        fclose(outfile);
  613. X        fclose(infile);
  614. X    }
  615. X    exit(0);
  616. X}
  617.  
  618. Xkey_get(mes)            /* get file key */
  619. Xchar *mes;
  620. X{    register int i, j;
  621. X    char linebuf[256];
  622. X    int count;
  623.  
  624. X    for (i=0; i<14; i++) keyy[i]=0;
  625.  
  626. X#ifdef LATTICE
  627. X#else
  628. X    gtty(0, &ttybuf);
  629. X    ttybuf.sg_flags &= ~ECHO;  /* turn off echoing */
  630. X    signal(SIGINT, bye);    /* catch ints */
  631. X    stty(0, &ttybuf);
  632. X#endif
  633.  
  634. X    printf("%s%s: ", mes, inname);
  635. X    fflush(stdout);
  636.  
  637. X    count = read(0, linebuf, 256);  /* read input line */
  638. X    printf("\n");
  639.  
  640. X#ifndef LATTICE
  641. X    ttybuf.sg_flags |= ECHO;      /* restore echo */
  642. X    stty(0, &ttybuf);
  643. X#endif
  644.  
  645. X    linebuf[count] = 0;  /* null terminate */
  646. X    if (linebuf[count-1] == '\n')  /* ignore any terminating newline */
  647. X    {  linebuf[count-1] = 0;
  648. X       count--;     
  649. X    }
  650. X    if (count > 8) count = 8;    /* only use 8 chars */
  651. X    for (i = j = 0; count--;)
  652. X       keyy[i++] = linebuf[j++];
  653. X}
  654.  
  655. Xpfile()                 /* process the file        */
  656. X{    register int m, nsave;
  657. X    register char *b;
  658. X    int j;
  659.  
  660. X    while (m = fread(buf, 1, 512, infile))
  661. X    {
  662. X        if ((nsave = m) < 0)    /* read error            */
  663. X        return(-1);
  664. X        for (b=buf; m>0;    /* encrypt/decrypt 1 buffer-full*/
  665. X        m -= 8, b += 8)        /* 8-byte blocks        */
  666. X        {   if (encrypting)
  667. X        {   if (m<8)        /* don't have a full 64 bits    */
  668. X            {   for (j=0; j<8-m; j++)
  669. X                b[m+j]=garbage(); /* fill block with trash  */
  670. X            nsave += 8-m;   /* complete the block        */
  671. X            }
  672. X            else j=0;    /* number of nulls in last block*/
  673. X            endes(b,b);    /* don't need diff input, output*/
  674. X        }
  675. X        else            /* decrypting            */
  676. X        {   if (m < 8) deout(b, 1); /* last byte in file: count */
  677. X            else
  678. X            {   dedes(b, b); /* decrypt and output block    */
  679. X            deout(b, 0);
  680. X            }
  681. X        }
  682. X        }
  683. X        if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
  684. X            return(-1);
  685. X    }
  686. X    /* have now encrypted/decrypted the whole file;
  687. X     * need to append the byte count for the last block if encrypting.
  688. X     */
  689. X    if (encrypting) fputc(8 - j, outfile);  /* how many good bytes? */
  690. X    return(0);
  691. X}
  692.  
  693. Xint outcount = 0;            /* see when caught up with delay*/
  694.  
  695. Xdeout(block,flag)            /* 1-block delay on output    */
  696. Xchar *block,flag;            /* 64-bit block, last block flag*/
  697. X{    static char last[8];        /* previous input block        */
  698. X    register int i;
  699. X/*    register char *c,*j;    */    /* rwo: unused    */
  700.  
  701. X    if (flag)            /* output the last few bytes    */
  702. X    {
  703. X        fwrite(last, 1, block[0] & 0377, outfile);
  704. X        return;
  705. X    }
  706. X    if (outcount++)            /* seen any blocks before?    */
  707. X        fwrite(last, 1, 8, outfile);
  708. X    for (i = 0; i < 8; i++) last[i] = block[i]; /* copy the block   */
  709. X}
  710.  
  711. Xgarbage()                /* generate garbage for filling */
  712. X/* This garbage should be as random as possible.  We're using subsequent calls
  713. X * on the timer, but ideally each byte should be uncorrelated.  Preferable
  714. X * would be to call the timer once and use it to initialize a dumb random
  715. X * number generator.
  716. X */
  717. X{
  718. X#ifdef LATTICE
  719. X    long timer(), ltime;
  720.  
  721. X    ltime = timer();
  722. X    return (int) ltime & 0377;
  723. X#else
  724. X    struct timeb tp;
  725.  
  726. X    ftime(&tp);            /* get current time        */
  727. X    return tp.millitm;        /* return time in milliseconds  */
  728. X#endif
  729. X}
  730.  
  731. X#ifndef LATTICE
  732.  
  733. X/* restore echo to tty and exit */
  734. Xbye()
  735. X{
  736. X    ttybuf.sg_flags |= ECHO;  /* restore echoing */
  737. X    stty(0, &ttybuf);
  738. X    exit(2);
  739. X}
  740.  
  741. X#endif
  742.  
  743. X#else       /* validation */
  744.  
  745. X#define VALFILE "valid.triples"
  746.  
  747. XFILE *fd;
  748.  
  749. Xchar key[8], plain[8], cipher[8], processed[8];
  750.  
  751. Xmain()  /* read key/plain/cipher triples until exhausted */
  752. X{    int count, i;
  753.  
  754. X    if ((fd = fopen(VALFILE, "r")) == NULL)
  755. X    {    fprintf(stderr, "Can't read %s.\n", VALFILE);
  756. X        exit(1);
  757. X    }
  758. X    count = 0;
  759. X    desinit(key);        /* initialize most of the arrays */
  760. X    while (readvals())
  761. X    {    kinit(key);    /* initialize key stuff        */
  762. X        printf("Key: "); writehex(key);
  763. X        printf("  Plain: "); writehex(plain);
  764. X        printf("  Cipher: "); writehex(cipher);
  765. X        printf("\n");
  766. X        endes(plain, processed); /* encipher the plaintext */
  767. X        printf("Encry:  "); writehex(processed);
  768. X        printf("\n");
  769. X        for (i = 0; i < 8; i++)
  770. X            if (processed[i] != cipher[i])
  771. X                printf("Encryption failed.\n");
  772. X        dedes(cipher, processed); /* decipher the ciphertext */
  773. X        printf("Decry:  "); writehex(processed);
  774. X        printf("\n");
  775. X        for (i = 0; i < 8; i++)
  776. X            if (processed[i] != plain[i])
  777. X                printf("Decryption failed.\n");
  778. X        count++;
  779. X    }
  780. X    printf("Processed %d tests.\n", count);
  781. X}
  782.  
  783. Xreadvals()    /* get the next legit triple */
  784. X{    int r;
  785.  
  786. X    r = readhex(key);
  787. X    readhex(plain);
  788. X    readhex(cipher);
  789. X    return r;
  790. X}
  791.  
  792. Xwritehex(str)   /* write the 64-bit hex string */
  793. Xchar *str;
  794. X{    int i;
  795.  
  796. X    for (i = 0; i < 8; i++)
  797. X        printf("%02x", str[i] & 0377);
  798. X}
  799.  
  800. Xhex(n)  /* convert hex nibble into integer */
  801. Xint n;
  802. X{
  803. X    if (n >= 'A' && n <= 'F') return n - 'A' + 10;
  804. X    return n - '0';
  805. X}
  806.  
  807. Xreadhex(str)    /* read 64 bits of hex code */
  808. Xchar *str;
  809. X{    int i, c;
  810.  
  811. X    for (i = 0; i < 8; i++)
  812. X    {    c = hex(getc(fd)) << 4;
  813. X        str[i] = c | hex(getc(fd));
  814. X    }
  815. X    while ((c = getc(fd)) == ' ' || c == '\t' || c == '\n');
  816. X    ungetc(c, fd);  /* skip to next field */
  817. X    return c != EOF;
  818. X}
  819.  
  820. X#endif
  821.  
  822. X/************ end scrydes ************/
  823.  
  824. @//E*O*F des.c//
  825. chmod u=rw,g=rw,o=rw $OUT
  826.  
  827. echo Inspecting for damage in transit...
  828. temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
  829. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  830. cat > $temp <<\!!!
  831.       13     127     699 README
  832.        7      27     159 Makefile
  833.       18     102     547 des.1
  834.      716    4037   21942 des.c
  835.      754    4293   23347 total
  836. !!!
  837. wc  README Makefile des.1 des.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  838. if test -s $dtemp ; then
  839.     echo "Ouch [diff of wc output]:"
  840.     cat $dtemp
  841.     STATUS=1
  842. elif test $STATUS = 0 ; then
  843.     echo "No problems found."
  844. else
  845.     echo "WARNING -- PROBLEMS WERE FOUND..."
  846. fi
  847. exit $STATUS
  848.